package com.whsxt.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.whsxt.common.AjaxResult;
import com.whsxt.common.Constants;
import com.whsxt.domain.Permission;
import com.whsxt.realm.ActiveUser;
import com.whsxt.service.PermissionService;
import com.whsxt.utils.Result2DTreeVoUtils;
import com.whsxt.vo.MenuVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private PermissionService permissionService;

    @RequestMapping("/doLogin.do")
    public AjaxResult login(String username, String password, String code, HttpSession session) {
        try {
            // 先比较验证码，再进行登录
            validateCode(code, session);
            // 执行到此处则证明验证，则输入正确
            // 获取token
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            // 获取subject
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            // 执行到此处不出异常则证明登陆成功
            return AjaxResult.ok();
        } catch (Exception e){
            e.printStackTrace();
            if(e instanceof UnknownAccountException){
                return AjaxResult.error(401, "用户不存在");
            }
            if(e instanceof IncorrectCredentialsException){
                return AjaxResult.error(401, "输入的密码错误");
            }
            return AjaxResult.error(e.getMessage());
        }
    }


    @RequestMapping("/doLogout.do")
    public AjaxResult logOut() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return AjaxResult.ok();
    }

    @RequestMapping("/code.do")
    public void getCode(HttpServletResponse response, HttpSession session) throws IOException {
        // 使用hutool产生一个验证码
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(130, 48, 1, 2);
        // 将验证码保存在session里以便取出做对比
        session.setAttribute(Constants.VALIDATE_STRING, shearCaptcha.getCode());
        // 获取输出流
        ServletOutputStream out = response.getOutputStream();
        // 将页面写出到页面
        shearCaptcha.write(out);
    }

    /**
     * 登录进来时加载菜单数据
     * @return
     */
    @RequestMapping("/menu.do")
    public List<MenuVo> Menu(){
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        // 查询储所有属于菜单的数据
        List<Permission> permissions = permissionService.selectPermsByUserId(activeUser.getUser().getId(), Arrays.asList(0, 1));
        // 将权限的数据转化为菜单的数据
        return Result2DTreeVoUtils.perms2MenuPlus(permissions);
    }

    /**
     * 验证码的校验
     */
    private void validateCode(String code, HttpSession session) {
        // 判断验证码是否为空
        if (!StringUtils.hasText(code)) {
            throw new IllegalArgumentException("验证码不能为空");
        }
        String sessionValidateCode = session.getAttribute(Constants.VALIDATE_STRING).toString();
        // 判断验证码是否输入正确
        if (!code.equalsIgnoreCase(sessionValidateCode)) {
            throw new IllegalArgumentException("验证码输入错误");
        }
        // 验证成功后，清除session里的验证码
        // session.removeAttribute(Constants.VALIDATE_STRING);
    }

}
